package handler

import (
	"context"
	"fmt"
	"github.com/asaskevich/govalidator"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"math/rand"
	"net/http"
	"seichat/biz"
	"seichat/common"
	"seichat/middlerware"
	"seichat/models"
	"seichat/service"
	"seichat/types"
	"strconv"
)

type UserHandler struct {
	userSvc service.UserService
}

func NewUserHandler(userSvc service.UserService) *UserHandler {
	return &UserHandler{userSvc: userSvc}
}
func (h *UserHandler) RegisterRoutes(router *gin.Engine) {
	u := router.Group("/user")
	u.POST("/login", h.LoginByNameAndPassWord)
	{
		u.Use(middlerware.JWT())
		u.GET("/list", h.List)
		u.POST("/add", h.NewUser)
		u.DELETE("/delete", h.DeleteUser)
		u.POST("/update", h.UpdateUser)
		u.POST("/user/redisMsg", h.SendRedisMsg)
	}
}

func (h *UserHandler) SendRedisMsg(c *gin.Context) {
	userIdA, _ := strconv.Atoi(c.PostForm("userIdA"))
	userIdB, _ := strconv.Atoi(c.PostForm("userIdB"))
	start, _ := strconv.Atoi(c.PostForm("start"))
	end, _ := strconv.Atoi(c.PostForm("end"))
	isRev, _ := strconv.ParseBool(c.PostForm("isRev"))
	userIdStr := strconv.Itoa(int(userIdA))
	targetIdStr := strconv.Itoa(int(userIdB))

	//userIdStr和targetIdStr进行拼接唯一key
	var key string
	if userIdA > userIdB {
		key = "msg_" + targetIdStr + "_" + userIdStr
	} else {
		key = "msg_" + userIdStr + "_" + targetIdStr
	}
	res, _ := h.userSvc.SendMessage(context.Background(), key, int64(start), int64(end), isRev)
	c.JSON(http.StatusOK, biz.Success(200, "ok", res))
}

func (h *UserHandler) List(ctx *gin.Context) {
	list, err := h.userSvc.GetUserList(context.Background())
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, biz.Fail(500, "获取用户列表失败"))
		return
	}
	ctx.JSON(http.StatusOK, list)
}
func (h *UserHandler) LoginByNameAndPassWord(ctx *gin.Context) {
	var req types.LoginByNameAndPassWordReq
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, biz.RequestParamError)
		return
	}
	resp, token, err := h.userSvc.LoginByNameAndPassWord(context.Background(), req.UserName, req.Password)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, biz.Fail(500, err.Error()))
		return
	}
	var userInfo map[string]interface{}
	userInfo["token"] = token
	userInfo["userId"] = resp.ID
	ctx.JSON(http.StatusOK, biz.Success(200, "登录成功", userInfo))
	return
}

func (h *UserHandler) NewUser(ctx *gin.Context) {
	name := ctx.Request.FormValue("name")
	password := ctx.Request.FormValue("password")
	repassword := ctx.Request.FormValue("Identity")
	if name == "" || password == "" || repassword == "" {
		ctx.JSON(http.StatusBadRequest, biz.RequestParamError)
		return
	}
	newUser, err := h.userSvc.NewUser(context.Background(), name, password, repassword)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, biz.InternalServerError)
		return
	}
	ctx.JSON(http.StatusOK, biz.Success(200, "新增用户成功", newUser))
}
func (h *UserHandler) UpdateUser(ctx *gin.Context) {
	user := models.User{}
	id, err := strconv.Atoi(ctx.Request.FormValue("id"))
	if err != nil {
		zap.S().Info("类型转换失败", err)
		ctx.JSON(http.StatusInternalServerError, biz.Fail(400, err.Error()))
		return
	}
	user.ID = uint(id)
	Name := ctx.Request.FormValue("name")
	PassWord := ctx.Request.FormValue("password")
	Email := ctx.Request.FormValue("email")
	Phone := ctx.Request.FormValue("phone")
	avatar := ctx.Request.FormValue("icon")
	gender := ctx.Request.FormValue("gender")
	if Name != "" {
		user.Name = Name
	}
	if PassWord != "" {
		salt := fmt.Sprintf("%d", rand.Int31())
		user.Salt = salt
		user.PassWord = common.SaltPassWord(PassWord, salt)
	}
	if Email != "" {
		user.Email = Email
	}
	if Phone != "" {
		user.Phone = Phone
	}
	if avatar != "" {
		user.Avatar = avatar
	}
	if gender != "" {
		user.Gender = gender
	}
	_, err = govalidator.ValidateStruct(user)
	if err != nil {
		zap.S().Info("参数不匹配", err)
		ctx.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, //  0成功   -1失败
			"message": "参数不匹配",
		})
		return
	}
	rsp, err := h.userSvc.UpdateUser(context.Background(), user)
	if err != nil {
		ctx.JSON(http.StatusOK, err)
		return
	}
	ctx.JSON(http.StatusOK, biz.Success(200, "修改成功", rsp))

}
func (h *UserHandler) DeleteUser(ctx *gin.Context) {
	user := models.User{}
	id, err := strconv.Atoi(ctx.Request.FormValue("id"))
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, biz.InternalServerError)
		return
	}
	user.ID = uint(id)
	err = h.userSvc.DeleteUser(context.Background(), user)
	if err != nil {
		ctx.JSON(http.StatusOK, err)
		return
	}
	ctx.JSON(http.StatusOK, biz.Success(200, "删除成功", nil))
}
